import { useDeviceInfo } from "@/store/deviceContext";
import { ScrollView, View } from "@tarojs/components";
import { useLayoutEffect, useRef, useState } from "react";
import style from "./index.module.scss";

type SliderPropsBase = {
  children?: React.ReactNode;
  hideScroll?: boolean;
};

export type DefaultSliderProps = SliderPropsBase & {
  type?: "default";
  themeColor?: string;
};
type HeroSliderProps = SliderPropsBase & {
  type: "hero";
  themeColor?: string;
};

/**
 * Note: assumes children of equal width - otherwise will need to use
 * the following on additional wrapper where you would need to include
 * a unique ID if more than one slider per page:
 *
 * Taro.createSelectorQuery().select(selector-string)
 *  .boundingClientRect((scrollArea) => {
 *    console.log("!!!", scrollArea.width);
 * }).exec()
 *
 *  */
const AbstractSlider = ({
  children,
  type = "default",
  themeColor,
  hideScroll = false,
}: DefaultSliderProps | HeroSliderProps) => {
  const scrollIndicator = useRef(null);
  const scrollContainer = useRef(null);
  const [indicatorWidth, setIndicatorWidth] = useState("0");
  const [scrollLeftTarget, setScrollLeftTarget] = useState(0);
  const [screenW, setScreenWidth] = useState(0);
  const [numSlides, setNumSlides] = useState(0);

  const { deviceInfoState } = useDeviceInfo();

  useLayoutEffect(() => {
    // @ts-ignore
    const numSlidesLocal = scrollContainer.current?.childNodes.length;
    setNumSlides(numSlidesLocal);
    setIndicatorWidth(String((1 / numSlidesLocal) * 100));
    const { screenWidth } = deviceInfoState;
    setScreenWidth(screenWidth);
  }, [deviceInfoState]);

  const onScroll = (e) => {
    const { scrollLeft, scrollWidth, deltaX } = e.detail;

    let scrollFract = scrollLeft / (scrollWidth - screenW);
    // Force alignment with edges
    if (Math.abs(deltaX) > 6) {
      if (scrollFract < 0.15) {
        scrollFract = 0;
      } else if (scrollFract > 0.85) {
        scrollFract = 1;
      }
    }
    setScrollLeftTarget(scrollFract * 100);
  };

  const singleSlide = numSlides === 1;

  return (
    <View
      className={`
        ${style["scroll-wrapper"]}
        ${style[`scroll-wrapper--${type}`]} 
      `}
    >
      {!singleSlide ? (
        <ScrollView
          scrollX
          showScrollbar={false}
          enhanced
          ref={scrollContainer}
          className={`
          ${style.slider} 
          slider--${type}
        `}
          onScroll={onScroll}
        >
          {children}
        </ScrollView>
      ) : (
        <View className={style["slider--single-slide"]}>{children}</View>
      )}
      {hideScroll ||
        (!singleSlide && (
          <View
            className={`
        scroll-indicator-wrapper'
        scroll-indicator-wrapper--${type} 
      `}
          >
            <View
              ref={scrollIndicator}
              style={{
                width: `${indicatorWidth}%`,
                transform: `translateX(${scrollLeftTarget * (numSlides - 1)}%)`,
                backgroundColor: themeColor,
              }}
              className={`
            slider-progress
            slider-progress--${type}
            `}
            />
          </View>
        ))}
    </View>
  );
};

export default AbstractSlider;
